package cn.harry.cabinet.server

import android.content.Context
import android.util.Log
import cn.harry.cabinet.repository.CardRepository
import cn.harry.cabinet.repository.ConfigurationRepository
import cn.harry.cabinet.repository.HardwareDeviceRepository
import cn.harry.cabinet.repository.OperationLogRepository
import cn.harry.cabinet.repository.UserRepository
import cn.harry.cabinet.server.routes.cardRoutes
import cn.harry.cabinet.server.routes.configurationRoutes
import cn.harry.cabinet.server.routes.featureRoutes
import cn.harry.cabinet.server.routes.hardwareDeviceRoutes
import cn.harry.cabinet.server.routes.operationLogRoutes
import cn.harry.cabinet.server.routes.userRoutes
import cn.harry.cabinet.utils.IpUtil
import io.ktor.http.HttpMethod
import io.ktor.http.HttpStatusCode
import io.ktor.serialization.kotlinx.json.json
import io.ktor.server.application.install
import io.ktor.server.engine.ApplicationEngine
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import io.ktor.server.plugins.cors.routing.CORS
import io.ktor.server.plugins.statuspages.StatusPages
import io.ktor.server.response.respond
import io.ktor.server.routing.routing
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json

/**
 * Ktor服务器管理类
 * 负责启动、停止和管理HTTP服务器
 */
class KtorServer(private val context: Context) {
    
    private var server: ApplicationEngine? = null
    private val serverScope = CoroutineScope(Dispatchers.IO)
    private val userRepository = UserRepository(context.applicationContext as android.app.Application)
    private val configurationRepository = ConfigurationRepository(context.applicationContext as android.app.Application)
    private val cardRepository = CardRepository(context.applicationContext as android.app.Application)
    private val hardwareDeviceRepository = HardwareDeviceRepository(context.applicationContext as android.app.Application)
    private val operationLogRepository = OperationLogRepository(context.applicationContext as android.app.Application)
    
    companion object {
        const val DEFAULT_PORT = 8888
        val DEFAULT_HOST: String = IpUtil.getLocalIpAddress() ?: "0.0.0.0"
        private const val TAG = "KtorServer"
    }
    
    /**
     * 启动服务器
     */
    fun start(port: Int = DEFAULT_PORT, host: String = DEFAULT_HOST) {
        if (server != null) {
            return // 服务器已经在运行
        }
        
        serverScope.launch {
            try {
                // 配置日志环境，避免Logback错误
                System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info")
                System.setProperty("org.slf4j.simpleLogger.logFile", "System.out")
                
                server = embeddedServer(Netty, port = port, host = host) {
                    // 配置CORS
                    install(CORS) {
                        anyHost()
                        allowHeader("*")
                        allowMethod(HttpMethod.Get)
                        allowMethod(HttpMethod.Post)
                        allowMethod(HttpMethod.Put)
                        allowMethod(HttpMethod.Delete)
                        allowMethod(HttpMethod.Options)
                    }
                    
                    // 配置内容协商
                    install(ContentNegotiation) {
                        json(Json {
                            prettyPrint = true
                            isLenient = true
                            ignoreUnknownKeys = true
                            encodeDefaults = true
                        })
                    }

                    // 配置状态页
                    install(StatusPages) {
                        exception<SerializationException> { call, cause ->
                            call.respond(HttpStatusCode.BadRequest, "Invalid request body: ${cause.message}")
                        }
                        exception<IllegalArgumentException> { call, cause ->
                            call.respond(HttpStatusCode.BadRequest, "Invalid request parameters: ${cause.message}")
                        }
                        exception<Exception> { call, cause ->
                            call.respond(HttpStatusCode.InternalServerError, "Internal server error: ${cause.message}")
                        }
                    }
                    
                    // 配置路由
                    routing {
                        userRoutes(userRepository)
                        configurationRoutes(configurationRepository)
                        featureRoutes(context)
                        cardRoutes(cardRepository)
                        hardwareDeviceRoutes(hardwareDeviceRepository)
                        operationLogRoutes(operationLogRepository)
                    }
                    
                    // 配置日志
                    Log.i(TAG, "Ktor服务器启动成功 - http://$host:$port")
                }
                
                server?.start(wait = true)
            } catch (e: Exception) {
                Log.e(TAG, "启动Ktor服务器失败: ${e.message}")
            }
        }
    }
    
    /**
     * 停止服务器
     */
    fun stop() {
        server?.let { currentServer ->
            try {
                Log.i(TAG, "正在停止Ktor服务器...")
                currentServer.stop(1000, 2000)
                server = null
                Log.i(TAG, "Ktor服务器已停止")
            } catch (e: Exception) {
                Log.e(TAG, "停止Ktor服务器时发生错误: ${e.message}")
                server = null // 即使出错也要清除引用
            }
        }
    }
    
    /**
     * 检查服务器是否正在运行
     */
    fun isRunning(): Boolean {
        return server != null
    }
    
    /**
     * 获取服务器状态信息
     */
    fun getServerInfo(): String {
        return if (isRunning()) {
            "服务器运行中 - http://$DEFAULT_HOST:$DEFAULT_PORT"
        } else {
            "服务器未运行"
        }
    }
} 